<?php

namespace seecms\wechat\lib;

use EasyWeChat\OfficialAccount\Application;
use seecms\See;
use seecms\SeeException;
use seecms\wechat\config\WechatConfig;

/**
 * 微信签名
 */
class WechatListen
{

    /**
     * @var Application|null
     */
    protected $easy_wechat_app = null;

    public function dispatch()
    {
        $this->log();

        // 验证消息是否来之微信
        if (!$this->checkSignature()) {
            echo '';
            exit();
        }

        $echo_str = $_GET['echostr'] ?? '';
        if ($echo_str) {
            echo $echo_str;
            exit();
        }

        $this->easy_wechat_app = WechatOfficialAccount::app();

        $this->easy_wechat_app->server->push(function ($content) {

            $msg_type = $content['MsgType'];
            if ($msg_type == 'event') {
                $class = new WechatEvent($this->easy_wechat_app, $content);
                $method = $content['Event'];
            } else {
                $class = new WechatMessage($this->easy_wechat_app, $content);
                $method = $content['MsgType'];
            }

            if (method_exists($class, $method)) {
                $result = $class->$method();
            } else {
                $result = '';
            }

            return $result;
        });

        return $this->easy_wechat_app->server->serve()->send();
    }

    /**
     * 验证微信消息来源
     * @return bool
     */
    protected function checkSignature(): bool
    {
        $signature = $_GET['signature'];
        $timestamp = $_GET['timestamp'];
        $nonce = $_GET['nonce'];

        $wechat = See::provider()->general->wechat;

        $token = $wechat['token'];
        $params = array($token, $timestamp, $nonce);
        sort($params, SORT_STRING);
        $new_signature = implode($params);
        $new_signature = sha1($new_signature);

        if ($new_signature == $signature) {
            return true;
        }

        return false;
    }

    protected function log()
    {
        if (WechatConfig::log()) {

            try {

                ck_directory(WechatConfig::log());

                $get = json_encode($_GET, JSON_UNESCAPED_UNICODE);
                $now = date('Y-m-d H:i:s');
                $input = file_get_contents('php://input');
                $content = <<<EOF
$now:
============================
get:
    $get
input:
    $input
EOF;
                file_put_contents(WechatConfig::log(), $content, FILE_APPEND);

            } catch (SeeException $exception) {

            }
        }
    }
}